package com.szh.easyexcel.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.MapUtils;
import com.alibaba.fastjson.JSON;
import com.szh.easyexcel.dto.ProductExcelDto;
import com.szh.easyexcel.dto.StudentExcelDto;
import com.szh.easyexcel.listener.ProductExcelListener;
import com.szh.easyexcel.service.ProductService;
import com.szh.easyexcel.service.StudentService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

/**
 * @author: SongZiHao
 * @date: 2023/5/27
 */
@RestController
@RequestMapping(value = "/excel")
public class EasyExcelController {

    private static final Logger LOGGER = LoggerFactory.getLogger(EasyExcelController.class);

    @Autowired
    private ProductService productService;

    @Autowired
    private StudentService studentService;

    /**
     * Excel上传，读Excel
     * @param file Excel文件
     * @return success
     * @throws IOException IOException
     */
    @PostMapping(value = "/upload")
    public String upload(MultipartFile file) throws IOException {
        LOGGER.info("Excel上传操作开始....");
        EasyExcel.read(file.getInputStream(), ProductExcelDto.class, new ProductExcelListener(productService))
                .sheet().headRowNumber(1).doRead();
        return "success";
    }

    /**
     * Excel下载，写Excel
     * @param response 响应对象
     * @throws IOException IOException
     */
    @GetMapping(value = "/download")
    public void download(HttpServletResponse response) throws IOException {
        LOGGER.info("Excel下载操作开始....");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        //这里URLEncoder.encode可以防止中文乱码 当然和EasyExcel没有关系
        String fileName = URLEncoder.encode("学生信息表", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        List<StudentExcelDto> studentExcelList = studentService.queryAllStudents();
        EasyExcel.write(response.getOutputStream(), StudentExcelDto.class)
                .sheet("学生信息表").doWrite(studentExcelList);
    }

    /**
     * Excel下载，并且失败的时候返回json
     * @param response 响应对象
     * @throws IOException IOException
     */
    @GetMapping(value = "/downloadFailedUsingJson")
    public void downloadFailedUsingJson(HttpServletResponse response) throws IOException {
        LOGGER.info("Excel下载操作开始....");
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            //这里URLEncoder.encode可以防止中文乱码 当然和EasyExcel没有关系
            String fileName = URLEncoder.encode("学生信息表", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            List<StudentExcelDto> studentExcelList = studentService.queryAllStudents();
            EasyExcel.write(response.getOutputStream(), StudentExcelDto.class)
                    //这里需要设置不关闭流
                    .autoCloseStream(Boolean.FALSE)
                    .sheet("学生信息表").doWrite(studentExcelList);
        } catch (Exception e) {
            LOGGER.error("Excel下载失败....");
            //重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = MapUtils.newHashMap();
            map.put("status", "failure");
            map.put("message", "Excel文件下载失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
        }
    }
}
